﻿using System;
using System.Collections.Generic;
using DL.Animation;
using DL.Characters.Player.FSM.State;
using DL.FSM;
using DL.Input;
using DL.Movement;

namespace DL.Characters.Player.FSM.StateMachine
{
    public class PlayerMoveStateMachine : DL.FSM.StateMachine
    {
        private List<Type> _types = new List<Type>()
        {
            // typeof(PlayerIdleState),
            typeof(PlayerLocomotionState),
            typeof(PlayerSprintState),

            // typeof(PlayerLocomotion8DirState),

            typeof(PlayerNullState),

            //特殊状态
            typeof(PlayerDodgeState),

            //跳跃状态
            typeof(PlayerJumpStartState),
            typeof(PlayerAirFallingState),
            typeof(PlayerReJumpState),
            typeof(PlayerJumpDownState),
            typeof(PlayerFastJumpDownState),

        };

        public CharacterInputSystem InputSystem { get; private set; }
        public Player Player { get; private set; }
        public PlayerMoveController MovementController { get; private set; }

        public PlayerMoveStateMachine(Player player)
        {
            Player = player;
            MovementController = Player.MovementController;
            InputSystem = CharacterInputSystem.Inst;
            m_Animator = Player.Animator;
            Initialize(Player.transform, _types, nameof(PlayerLocomotionState));

            //注册一个地面事件
            MovementController.CharacterIsOnGroundEvent += OnStableGroundChange;
        }

        protected void OnStableGroundChange(bool isGrounded)
        {
            if (isGrounded)
            {
                Player.Animator.SetBool(AnimatorParameter.Fall, false);
                Player.Animator.SetBool(AnimatorParameter.OnGrounded, true);

            }
            else
            {
                //可能会出现一种极端情况，也就是踩空了0.几秒但是这里还是会被执行
                Player.Animator.SetBool(AnimatorParameter.Fall, true);
                Player.Animator.SetBool(AnimatorParameter.OnGrounded, false);
            }
        }

        /// <summary>
        /// 扩展,处于aniName播放阶段且不在T状态下转换为T
        /// </summary>
        /// <param name="aniName"></param>
        /// <param name="priority"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public bool ChangeStateByAniName<T>(string aniName, int priority = 0) where T : class, IState
        {
            if (AnimatorStateInfo.IsName(aniName) &&
                !IsSameStateWithCurrentState<T>() &&
                !AnimatorIsInTransition)
            {
                return ChangeState<T>(priority);
            }

            return false;
        }

        public bool ChangeStateByAniTag<T>(string tag, int priority = 0) where T : class, IState
        {
            if (AnimatorStateInfo.IsTag(tag) &&
                !IsSameStateWithCurrentState<T>() &&
                !AnimatorIsInTransition)
            {
                return ChangeState<T>(priority);
            }

            return false;
        }
    }
}